#ifndef CELL_HPP
#define CELL_HPP

#include "meshTypes_fwd.hpp"
#include "cellBase.hpp"

namespace hms {

template<>
class CellTraits<Cell>
{
public:
	using MeshType    = Mesh;
	using CentroidType = Matrix2Xs::ConstColXpr;
	using EdgeIndices = const Eigen::VectorBlock<Array4Xi::ConstColXpr>;
};

/**
 * @brief Cell class for Mesh
 * 
 * Thin wrapper class analogous to Edge.
 */
class Cell : public CellBase<Cell>
{
public:
	using Traits = CellTraits<Cell>;
	using MeshType     = Traits::MeshType;
	using CentroidType = Traits::CentroidType;
	using EdgeIndices  = Traits::EdgeIndices;

private:
	const Cells& m_cells;
	const Index m_index;

public:
	Cell( const Cells&, Index );
	
	auto cells() const -> const Cells&;

private:
	auto meshImp      () const -> const Mesh&;
	auto indexImp     () const -> Index;

	auto areaImp      () const -> scalar;
	auto circumfImp   () const -> scalar;
	auto centroidImp  () const -> CentroidType;
	
	auto edgeImp      () const -> Index;
	auto edgesImp     () const -> EdgeIndices;
	auto nEdgesImp    () const -> char;
	auto isGhostImp   () const -> bool;
	auto domainCellImp() const -> Cell;
	
	/* medium cost functions */
	auto isBoundaryImp() const -> bool;

	/* high cost functions */
	auto neighboursImp() const -> ArrayXi;
	auto verticesImp  (bool ordered) const -> ArrayXi;

	friend CellBase;
	friend Mesh;
};

} // end namespace hms

#endif